<template>
  <ul class="draggable-list">
    <li
        v-for="(item, index) in items"
        :key="item.id || index"
        class="list-item"
        draggable="true"
        @dragstart="handleDragStart(index)"
        @dragover.prevent="handleDragOver(index)"
        @dragenter.prevent="handleDragEnter(index)"
        @dragleave="handleDragLeave"
        @drop.prevent="handleDrop(index)"
        :class="{ 'dragging-over': dragOverIndex === index }"
    >
      <slot name="item" :item="item" :index="index"></slot>
    </li>
  </ul>
</template>

<script setup lang="ts">
import { ref } from 'vue'

const props = defineProps({
  items: {
    type: Array,
    required: true
  }
})

const emit = defineEmits(['update:items'])

const dragItemIndex = ref<number | null>(null)
const dragOverIndex = ref<number | null>(null)

const handleDragStart = (index: number) => {
  dragItemIndex.value = index
}

const handleDragOver = (index: number) => {
  dragOverIndex.value = index
}

const handleDragEnter = (index: number) => {
  dragOverIndex.value = index
}

const handleDragLeave = () => {
  dragOverIndex.value = null
}

const handleDrop = (dropIndex: number) => {
  if (dragItemIndex.value === null) return

  const newItems = [...props.items]
  const [removed] = newItems.splice(dragItemIndex.value, 1)
  newItems.splice(dropIndex, 0, removed)

  emit('update:items', newItems)
  resetDragState()
}

const resetDragState = () => {
  dragItemIndex.value = null
  dragOverIndex.value = null
}
</script>

<style scoped>
.draggable-list {
  list-style: none;
  padding: 0;
  margin: 0;
}

.list-item {
  padding: 12px 16px;
  margin: 8px 0;
  background-color: #ffffff;
  border-radius: 6px;
  border: 1px solid #ebeef5;
  cursor: move;
  transition: all 0.3s ease;
  box-shadow: 0 1px 4px rgba(0, 0, 0, 0.05);
}

.list-item:hover {
  background-color: #f5f7fa;
  border-color: #c0c4cc;
}

.list-item.dragging-over {
  background-color: #ecf5ff;
  border: 1px dashed #409eff;
  box-shadow: 0 2px 12px 0 rgba(64, 158, 255, 0.2);
}
</style>